package pre;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: leetcode
 * @author: jzhou
 * @date: 2022-10-27 16:59
 * @version: 1.0
 * @description: 学习 HashMap ConcurrentHashMap
 **/
public class MyHashMap<K,V> implements MyMap<K,V>{

	MyEntry<K,V>[] table = null;

	public MyHashMap() {
		this.table = new MyEntry[16];
	}

	/**
	 * 1、 对 key 进行取模，算出对应的数组下标
	 * 2、 判断数组对应节点是否为空，为空直接插入
	 * 		不为空则使用链表存储
	 *
	 */

	static class MyEntry<K,V> implements MyMap.MyEntry<K,V>{

		K k;
		V v;
		int index;
		MyEntry<K,V> next;

		public MyEntry(K k, V v, int index, MyEntry<K, V> next) {
			this.k = k;
			this.v = v;
			this.index = index;
			this.next = next;
		}

		@Override
		public K getKey() {
			return k;
		}

		@Override
		public V getValue() {
			return v;
		}

		@Override
		public V setValue(V value) {
			return null;
		}
	}

	@Override
	public int size() {
		return 0;
	}

	@Override
	public V put(K key, V value) {
		int i = hash(key);
		// 当对应下标为空时，直接插入
		if (table[i] == null) {
			table[i] = new MyEntry<>(key,value,i,null);
		}else {// 不为空时插入 写入链表
			MyEntry<K,V> last = findLast(table[i]);
			last.next = new MyEntry<>(key,value,i,null);
		}
		return null;
	}

	private MyEntry<K,V> findLast(MyEntry<K,V> head) {

		for(MyEntry<K,V> p,r = head;;){
			if ((p=r.next) == null)
				return r;
			r = p;
		}
	}

	private int hash(K key) {
		int i = key.hashCode() % 8;
		return  i;
	}

	@Override
	public V remove(K key) {
		return null;
	}

	@Override
	public V get(K key) {
		int index = hash(key);
		return findValue(table[index],key);
	}

	private V findValue(MyEntry<K, V> entry, K key) {
		if (entry != null){
			if (key.equals(entry.getKey()) || key == entry.getKey()){
				return entry.getValue();
			}else {
				return findValue(entry.next,key);
			}
		}
		return null;
	}

	public static void main(String[] args) {

		ConcurrentHashMap<String,String> conn = new ConcurrentHashMap<>();
		conn.put("a","a");
		conn.put("b","b");
		conn.put("c","c");



		MyHashMap<String, String> hashMap = new MyHashMap<>();
		hashMap.put("1","1");
		hashMap.put("2","1");
		hashMap.put("3","1");
		hashMap.put("4","1");
		hashMap.put("5","1");
		hashMap.put("6","1");
		hashMap.put("7","1");
		hashMap.put("8","1");
		hashMap.put("9","1");
		hashMap.put("10","1");
		System.out.println(1);
		System.out.println(hashMap.get("9"));
	}
}



interface MyMap<K,V>{

	int size();
	V put(K key, V value);
	V remove(K key);
	V get(K key);

	static interface MyEntry<K,V>{
		K getKey();
		V getValue();
		V setValue(V value);
	}
}
